package com.zhangsheng.component;

import com.zhangsheng.annotation.NoRepeat;
import com.zhangsheng.api.CommonResult;
import com.zhangsheng.entity.model.Order;
import com.zhangsheng.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @author 张晟
 * @version 1.0
 * @date 2023/1/5 9:29
 */
@Aspect
@Slf4j
@Component
public class  NoRepeatAspect {

    @Autowired
    private RedisService redisService;

    @Pointcut("@annotation(noRepeat)")
    public void pointCut(NoRepeat noRepeat) {}

    @Around(value = "pointCut(noRepeat)", argNames = "joinPoint,noRepeat")
    public CommonResult<Order> around(ProceedingJoinPoint joinPoint , NoRepeat noRepeat) throws Throwable {
        log.info("提交订单开始");
        CommonResult<Order> result = null;
        long releaseTime = noRepeat.expireTime();
        log.info("leaseTime : " + releaseTime);
        String accountUriLockKey = "accountUriLock";
        RLock lock = Redisson.create().getLock(accountUriLockKey);
        boolean tryLock;
        tryLock = lock.tryLock(15, releaseTime, TimeUnit.SECONDS);
        log.info("tryLock : " + tryLock);
        if (tryLock) {
            try {
                result = (CommonResult<Order>) joinPoint.proceed();
                log.info("正常提交order : " + result.getData());
                redisService.createOrderByRedis(result.getData());
            }catch (Exception e) {
                throw new RuntimeException("程序异常");
            }
        }else {
            log.info("重复提交 : " + accountUriLockKey);
        }
        lock.unlock();
        log.info("提交订单结束");
        return result;
    }

}
